package com.apobates.jforum.grief.aurl.test;

import com.apobates.jforum.grief.aurl.AUrl;
import com.apobates.jforum.grief.aurl.convertor.MapConvertor;
import com.apobates.jforum.grief.aurl.core.AUrlMeta;
import com.apobates.jforum.grief.aurl.core.AUrlMetaBuilder;
import com.apobates.jforum.grief.aurl.executor.*;
import com.apobates.jforum.grief.aurl.parser.AntlrParser;
import com.apobates.jforum.grief.aurl.selector.FileTypeSelector;
import com.apobates.jforum.grief.aurl.parser.PatternParser;
import com.apobates.jforum.grief.aurl.utils.*;
import com.apobates.jforum.grief.aurl.utils.defend.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.assertj.core.data.Index;

import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
import static org.assertj.core.api.BDDAssertions.then;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

public class Base {
    private AUrlMeta urlRawMeta;
    private String url="https://www.google.com/search?q=baeldung";
    private String uri="https://jwage.com:443/about/me?param1=value1&param2=value2#about";

    @BeforeEach
    public void init() {
        urlRawMeta = AUrl.create().scheme("https").host("www.google.com").path("search").queryParam("q", Arrays.asList("baeldung")).build();
    }

    @Test
    public void testBuild(){
        assertEquals(urlRawMeta.toString(), url);
    }

    @Test
    public void testJoin(){
        assertEquals(urlRawMeta.join("/page").toString(), "https://www.google.com/page?q=baeldung");
    }

    @Test
    public void testRelative(){
        assertEquals(urlRawMeta.relative("../look?p=1&word=php").toString(), "https://www.google.com/look?p=1&word=php");
    }

    @Test
    public void testClipQuery(){
        ClipParameterExecutor executor = urlRawMeta
                .clipQueryParam()
                .delete("q")
                .add("product", 1)
                .add("member", 11)
                .replace("product", 1010)
                .add("product", 1011)
                .add("page", 1,2);
        assertEquals(executor.getBuilder().toString(), "https://www.google.com/search?member=11&product=1010&product=1011&page=1&page=2");

    }

    @Test
    public void testCusExecutor(){
        ClipParameterExecutor execute = urlRawMeta.execute(ClipParameterExecutor.class);
        execute = execute.delete("q")
                .add("product", 1)
                .add("member", 11)
                .replace("product", 1010)
                .add("product", 1011)
                .add("page", 1,2);
        // assertEquals(execute.getBuilder().toString(), "https://www.google.com/search?product=1010&product=1011&member=11&page=1&page=2");
        assertNotEquals(execute.getBuilder().toString(), urlRawMeta.toString());
    }

    @Test
    public void testCreate() {
        AUrlMeta rawMeta = AUrl.create(uri).build();
        assertAll("rawMeta",
                () -> assertEquals("https", rawMeta.getScheme()),
                () -> assertEquals("jwage.com", rawMeta.getHost()),
                () -> assertEquals("/about/me", rawMeta.getPath()),
                () -> assertEquals("443", rawMeta.getPort()),
                () -> assertEquals("param1=value1&param2=value2", rawMeta.getQuery()),
                () -> assertEquals("about", rawMeta.getFragment())
        );
    }

    @Test
    public void testPattern() {
        AUrlMeta rawMeta = AUrl.parse(uri, new PatternParser());
        assertAll("rawMeta",
                () -> assertEquals("https", rawMeta.getScheme()),
                () -> assertEquals("jwage.com", rawMeta.getHost()),
                () -> assertEquals("/about/me", rawMeta.getPath()),
                () -> assertEquals("443", rawMeta.getPort()),
                () -> assertEquals("param1=value1&param2=value2", rawMeta.getQuery()),
                () -> assertEquals("about", rawMeta.getFragment())
        );
    }

    @Test
    public void testAntlr4() {
        AUrlMeta rawMeta = AUrl.parse(uri);
        assertAll("rawMeta",
                () -> assertEquals("https", rawMeta.getScheme()),
                () -> assertEquals("jwage.com", rawMeta.getHost()),
                () -> assertEquals("/about/me", rawMeta.getPath()),
                () -> assertEquals("443", rawMeta.getPort()),
                () -> assertEquals("param1=value1&param2=value2", rawMeta.getQuery()),
                () -> assertEquals("about", rawMeta.getFragment())
        );
    }

    @Test
    public void testShortURL(){
        AUrlMeta rawMeta = AUrl.parse(uri);
        // 短地址
        ShortUrlExecutor shortUrlExecutor = rawMeta.execute(ShortUrlExecutor.class);
        ShortUrlExecutor.Config config = ShortUrlExecutor.Config
                .create("http://z.cn")
                .path("u")
                .length(8)
                .algorithm(ShortUrlExecutor.Algorithm.SHA1);
        String surl=shortUrlExecutor.generate(config);
        assumeTrue(surl.length() == 22);
        // assumeTrue(surl.equals(shortUrlExecutor.getBuilder().toString()));
    }

    @Test
    public void testNormalize(){
        String nurl = AUrl.normalize("http://www.example.com/app/#/home?a=1").orElse("about:blank");
        assertEquals(nurl, "http://www.example.com/app/home?a=1");
    }

    @Test
    public void testSPAURL(){
        boolean spaurl = AUrl.isSPAUrl("http://www.example.com/app/#/home?a=1#b");
        assumeTrue(spaurl);
    }

    @Test
    public void testFile(){
        String mpl = "https://p2.music.126.net/FAA_2pnfUUPUcUOnjEyvMg==/109951163237439720.jpg?size=945x945";
        AUrlMeta mp = AUrl.parse(mpl, new PatternParser());
        try {
            String file = new URL(mpl).getFile();
            assertEquals(file, mp.getFile());
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Test
    public void testSameFile(){
        String a = "http://www.google.com/search?q=java";
        String b = "http://www.google.com/search";
        AUrlMeta mp = AUrl.parse(a, new PatternParser());
        assumeTrue(mp.isSameFile(b));
    }

    @Test
    public void testURLSameFile(){
        String a = "https://www.google.com/search?product=1010&product=1011&member=11&member=11&page=1&page=2";
        String b = "https://www.google.com/search";
        AUrlMeta mp = AUrl.parse(b);
        assumeTrue(mp.isSameFile(a));
    }

    @Test
    public void testGetParam(){
        String a = "https://www.google.com/search?product=1010&product=1011&member=11&member=11&page=1&page=2";
        AUrlMeta mp = AUrl.parse(a);
        assertEquals(mp.getQueryParam("product").orElse("x"), "1010");
    }

    @Test
    public void testAllParams(){
        String a = "https://www.google.com/search?product=1010&product=1011&member=11&member=11&page=1&page=2";
        AUrlMeta mp = AUrl.parse(a);
        Collection<String> product = mp.getQueryParams("product");
        assertThat(product)
                .hasSize(2)
                .contains("1010")
                .contains("1011");
    }

    @Test
    public void testPathSegment(){
        String a = "https://www.youtube.com/user/WatchTheDaily/videos/130342.mp4";
        AUrlMeta mp = AUrl.parse(a);
        List<String> pathSegments = new ArrayList<>(mp.getPathSegments());

        assertThat(pathSegments)
                .hasSize(4)
                .contains("user", Index.atIndex(0))
                .contains("WatchTheDaily", Index.atIndex(1))
                .contains("videos", Index.atIndex(2))
                .contains("130342.mp4", Index.atIndex(3));
    }

    @Test
    public void testBuildPathSegment(){
        AUrlMeta meta = AUrl.create()
                .scheme("https")
                .host("www.youtube.com")
                .pathSegment("user", "WatchTheDaily", "videos", "130342.mp4")
                .build();
        List<String> pathSegments = new ArrayList<>(meta.getPathSegments());

        assertThat(pathSegments)
                .hasSize(4)
                .contains("user", Index.atIndex(0))
                .contains("WatchTheDaily", Index.atIndex(1))
                .contains("videos", Index.atIndex(2))
                .contains("130342.mp4", Index.atIndex(3));
    }

    @Test
    public void testBatch(){
        List<String> t = List.of(
                "https://www.google.com/search?product=1010&product=1011&member=11&member=11&page=1&page=2",
                "http://www.google.com/search?q=java",
                "https://p2.music.126.net/FAA_2pnfUUPUcUOnjEyvMg==/109951163237439720.jpg?size=945x945",
                "http://www.example.com/app/#/home?a=1#b",
                "https://jwage.com:443/about/me?param1=value1&param2=value2#about"
        );
        assumeTrue(t.stream().map(AUrl::parse).filter(AUrlMeta::isHttps).count() == 3);
    }

    @Test
    public void testEncode(){
        String a = "https://www.google.com/search?word=java stream map";
        AUrlMeta temp = AUrl.parse(a);
        assertEquals("https://www.google.com/search?word=java%20stream%20map", temp.toString());
    }

    @Test
    public void testFileExt(){
        String a = "https://csdnimg.cn/release/phoenix/vendor/pagination/paging.css?q=word&zip=1";
        String b = "https://ts1.cn.mm.bing.net/th/id/R-C.745acb7b400ce0c34da4e7450bfa1d10?rik=ZYSWspMbbWjVSw&pid=ImgRaw&r=0&sres=1&sresct=1";
        String c = "https://img-s-msn-com.akamaized.net/tenant/amp/entityid/AA1gxj4N.img?w=1920&h=1080&q=60&m=2&f=jpg";
        String d = "https://img.ithome.com/newsuploadfiles/2023/9/dfa1d3dc-a259-4dc6-8676-cd40d3ff9570.jpg?x-bce-process=image/format,f_auto";
        FileTypeSelector selector = AUrl.parse(d).fileType();
        assertThat(selector).matches(p -> p.isImage()).matches(p->p.isValide(ext->ext.equals("jpg")));
    }

    @Test
    public void testBuildTemplate(){
        AUrlMetaBuilder empty = AUrlMetaBuilder.getInstance();
        TBean bean = new TBean(1, "modify");
        AUrlMetaBuilder ins = AUrl.create("http://localhost/api/employees/{id}/{action}");
        AUrlMeta build = ins.templateByObj(bean);
        assertEquals(build.toString(), "http://localhost/api/employees/1/modify");
    }
    @Test
    public void testBuildMapTemplate(){
        AUrlMetaBuilder empty = AUrlMetaBuilder.getInstance();
        AUrlMetaBuilder ins = AUrl.create("http://localhost/api/employees/{id}/{action}");
        AUrlMeta build = ins.templateByMap(Map.<String,String>of("id", "1", "action", "modify"));
                // .template(Collections.emptyMap()); // template(Map.of("id", 1, "action", "modify"));
        assertEquals(build.toString(), "http://localhost/api/employees/1/modify");
    }
    @Test
    public void testExtract(){
        AUrlMeta build = AUrl.create("http://localhost/api/employees/{id}/{action}").build();
        PathParamExecutor execute = build.execute(PathParamExecutor.class);
        TBean bean = new TBean(1, "modify");
        String bb = execute.extractToString(bean);
        assumeTrue(bb.equals(execute.extract(bean).toString()) && bb.equals("http://localhost/api/employees/1/modify"));
    }

    @Test
    public void testTemplate(){
        AUrlMeta build = AUrl.create("http://localhost/api/employees/{id}/{action}").build();
        PathParamExecutor execute = build.execute(PathParamExecutor.class);
        String replacePath = execute.replace("id", "1", "action", "revoke");
        assertEquals(replacePath, "/api/employees/1/revoke");
    }

    @Test
    public void testTri(){
        AUrlMeta build = AUrl.create("http://localhost/api/employees/{id}/{attr}/{val}").build();
        PathParamExecutor execute = build.execute(PathParamExecutor.class);
        String replacePath = execute.replace("id", "1", "attr", "nickname", "val", "xiaofanku");
        assertEquals(replacePath, "/api/employees/1/nickname/xiaofanku");
    }

    @Test
    public void testMapTemplate(){
        AUrlMeta build = AUrl.create("http://localhost/api/employees/{id}/{attr}/{val}").build();
        PathParamExecutor execute = build.execute(PathParamExecutor.class);
        String replacePath = execute.replace(Map.of("id", "1", "attr", "nickname", "val", "xiaofanku"));
        assertEquals(replacePath, "/api/employees/1/nickname/xiaofanku");
    }

    @Test
    public void testExtractTemplate(){
        AUrlMeta build = AUrl.create("http://localhost/api/employees/{id}/{action}").build();
        PathParamExecutor execute = build.execute(PathParamExecutor.class);
        List<Map<String,String>> list = new ArrayList<>(4);
        list.add(Map.of("id", "1", "action", "revoke"));
        list.add(Map.of("id", "2", "action", "avatar"));
        list.add(Map.of("id", "3", "action", "home"));
        list.add(Map.of("id", "4", "action", "auth"));
        List<String> rs = execute.extractByMapToString(list).collect(Collectors.toList());
        assertThat(rs)
                .contains(
                    "http://localhost/api/employees/1/revoke",
                    "http://localhost/api/employees/2/avatar",
                    "http://localhost/api/employees/3/home",
                    "http://localhost/api/employees/4/auth")
                .hasSize(4);
    }

    @Test
    public void testExtractObjSet(){
        AUrlMeta build = AUrl.create("http://localhost/api/employees/{id}/{action}").build();
        PathParamExecutor execute = build.execute(PathParamExecutor.class);
        List<TBean> list = new ArrayList<>(4);
        list.add(new TBean(1, "revoke"));
        list.add(new TBean(2, "avatar"));
        list.add(new TBean(3,  "home"));
        list.add(new TBean(4,  "auth"));
        List<String> rs = execute.extractByObjectToString(list).collect(Collectors.toList());
        assertThat(rs)
                .contains(
                        "http://localhost/api/employees/1/revoke",
                        "http://localhost/api/employees/2/avatar",
                        "http://localhost/api/employees/3/home",
                        "http://localhost/api/employees/4/auth")
                .hasSize(4);
    }

    @Test
    public void testCurly(){
        // getSymbol::{action} /r {id}
        // getNames::action /r id
        Iterable<String> names = new CurlyBraceSymbol("/api/employees/{id}/{action}").getNames();
        //List<String> result = new ArrayList<>();
        //names.forEach(result::add);
        assertThat(names).contains("action", "id").hasSize(2);
    }

    @Test
    public void testCurlyBean(){
        CurlyBraceSymbol curlyBraceSymbol = new CurlyBraceSymbol("/api/employees/{id}/{action}");
        String modify = curlyBraceSymbol.replace(new TBean(1, "modify"));
        assertEquals(modify, "/api/employees/1/modify");
    }

    @Test
    public void testSymbol(){
        AUrlMeta build = AUrl.create("http://localhost/api/employees/{id}/{action}").build();
        assumeTrue(build.hasPathVariable() && !urlRawMeta.hasPathVariable());
    }

    @Test
    public void testExecutorFactory(){
        PathParamExecutor ppe = AUrl.execute(PathParamExecutor.class).arg("http://localhost/api/employees/{id}/{action}");
        String replacePath = ppe.replace("id", "1", "action", "revoke");
        assertEquals(replacePath, "/api/employees/1/revoke");
    }

    @Test
    public void testSelectorFactory(){
        String d = "https://img.ithome.com/newsuploadfiles/2023/9/dfa1d3dc-a259-4dc6-8676-cd40d3ff9570.jpg?x-bce-process=image/format,f_auto";
        FileTypeSelector selector = AUrl.select(FileTypeSelector.class).arg(d);
        assertThat(selector).matches(p -> p.isImage()).matches(p->p.isValide(ext->ext.equals("jpg")));
    }

    @Test
    public void testConvertorFactory(){
        String b = "https://img.ithome.com/newsuploadfiles/2023/9/dfa1d3dc-a259-4dc6-8676-cd40d3ff9570.jpg";
        Map<String, String> map = AUrl.convert(new MapConvertor()).arg(b);
        map.entrySet().stream().forEach(System.out::println);
    }

    @Test
    public void testConvertorMapper(){
        String b = "https://img.ithome.com/newsuploadfiles/2023/9/dfa1d3dc-a259-4dc6-8676-cd40d3ff9570.jpg";
        Map<String, String> map = AUrl.convert(new MapConvertor()).use(new AntlrParser()).apply(b);
        map.entrySet().stream().forEach(System.out::println);
    }

    @Test
    public void testDAException(){
        final TBean tb = null;
        final TBean tb1 = new TBean(1, "modify");
        IllegalArgumentException exception = catchIllegalArgumentException(() -> {
            PredicateQueue.<TBean>require().asserts(Assertion.single(tb)).suspend(); });
        assertThat(exception).isInstanceOf(IllegalArgumentException.class);
    }

    @Test
    public void testDADefault(){
        final TBean tb = null;
        final TBean tb1 = new TBean(1, "modify");
        Optional<TBean> ins = PredicateQueue.<TBean>require().asserts(Assertion.single(tb)).get(tb1);
        assertThat(ins).matches(obj -> obj.get().getId() == 1);
    }

    @Test
    public void testDAOptional(){
        final TBean tb = null;
        final TBean tb1 = new TBean(1, "modify");
        Optional<TBean> ins = PredicateQueue.<TBean>require().asserts(Assertion.single(tb)).get();
        assertThat(ins).isNotPresent();
    }

    @Test
    public void testDANPE(){
        final TBean tb = null;
        final TBean tb1 = new TBean(1, "modify");
        NullPointerException exception = catchNullPointerException(() -> {
            PredicateQueue.<TBean>require().asserts(Assertion.single(tb)).suspend(NullPointerException::new);
        });
        assertThat(exception).isInstanceOf(NullPointerException.class);
    }

    @Test
    public void testDAMultiExp(){
        NullPointerException exception = catchNullPointerException(() -> {
            PredicateQueue.<String>require().asserts(Assertion.multi("163.com", null, "qq.com")).suspend(NullPointerException::new);
            // DefendAssert.multi("163.com", null, "qq.com").notNull().suspend(NullPointerException::new);
        });
        assertThat(exception).isInstanceOf(NullPointerException.class);
    }

    @Test
    public void testDAMultiExpMessage(){
        IllegalArgumentException exception = catchIllegalArgumentException(() -> {
            // DefendAssert.multi("163.com", null, "qq.com").notNull().suspend();
            PredicateQueue.<String>require().asserts(Assertion.multi("163.com", null, "qq.com")).suspend();
        });
        assertThat(exception).isInstanceOf(IllegalArgumentException.class).hasMessage("目标参数不可用, 参数:1");
        //DefendAssert.multi("163.com", null, "qq.com").notNull().suspend();
    }

    @Test
    public void testDAMultiExpRs(){
        /*
        Tuple<String,String,String> rs = DefendAssert.multi("163.com", null, "qq.com").notNull().get((args, failIndexList)->{
            String left = failIndexList.contains(0) ? "NPE" : args.get(0);
            String middle = failIndexList.contains(1) ? "NPE" : args.get(1);
            String right = failIndexList.contains(2) ? "NPE" : args.get(2);
            return Tuple.of(left, middle, right);
        });
        */
        Tuple<String,String,String> rs = PredicateQueue.<String>require().asserts(Assertion.multi("163.com", null, "qq.com")).get((args, failIndexList)->{
            String left = failIndexList.contains(0) ? "NPE" : args.get(0);
            String middle = failIndexList.contains(1) ? "NPE" : args.get(1);
            String right = failIndexList.contains(2) ? "NPE" : args.get(2);
            return Tuple.of(left, middle, right);
        });

        assertThat(rs).matches(ins->ins.middle().equals("NPE")).matches(ins->ins.left().equals("163.com"));
    }

    @Test
    public void testDAMultiResult(){
        List<String> rs = PredicateQueue.<String>require().asserts(Assertion.multi("163.com", null, "qq.com")).getElse("NPE");
                            // DefendAssert.multi("163.com", null, "qq.com").notNull().getElse("NPE");

        assertThat(rs).matches(list->list.get(1).equals("NPE"))
                .matches(list->list.get(0).equals("163.com"))
                .hasSize(3);
    }

    @Test
    public void testDAAfter(){
        TBean tb=null;
        DefendAssert<String> mul = PredicateQueue.<String>require().asserts(Assertion.multi("163.com", null, "qq.com"));
                                    // DefendAssert.multi(null, "163.com").notNull();
        DefendAssert<TBean> sig = PredicateQueue.<TBean>require().asserts(Assertion.single(tb));
                                    // DefendAssert.single(tb).notNull();
        IllegalArgumentException exception = catchIllegalArgumentException(() -> {
            sig.after(mul).suspend();
        });
        assertThat(exception).isInstanceOf(IllegalArgumentException.class).hasMessage("目标参数不可用");
    }
    @Test
    public void testDAEmpty(){
        DefendAssert<Object> sig = PredicateQueue.require().asserts(Assertion.empty()).before(DefendAssert.empty());
        sig.suspend();
    }
    @Test
    public void testDAPredicate(){
        Map<String,String> target = new HashMap<>();
        target.put("age", "12");
        target.put("name", "mandy");
        /*
        Stream<Pair<Integer,String>> validate = DefendAssert.single(target).notNull().notEmpty().contains(Map.of("height", "xiao")).validate(
                (map) -> {
                    return map.entrySet().stream().map(entry -> Pair.<Integer,String>of(entry.getKey(), String.join(",", entry.getValue())));
                },
                (ar)->String.format("[%s]%s", ar.label(), ar.message()));
        */
        Stream<Pair<Integer,String>> validate = PredicateQueue.<Map<String,String>>require()
                .notEmpty()
                .contains(Map.of("height", "xiao"))
                .asserts(Assertion.single(target))
                .validate(
                    (map) -> {
                        return map.entrySet().stream().map(entry -> Pair.<Integer,String>of(entry.getKey(), String.join(",", entry.getValue())));
                    },
                    (ar)->String.format("[%s]%s", ar.label(), ar.message()));
        validate.forEach(pair->System.out.println(String.format("index=%d, has exception=%s", pair.left(), pair.right())));
    }

    @Test
    public void testDASPredicate(){
        Set<String> target = new HashSet<>();
        target.add("xiao");
        target.add("pktmandy");

        Set<String> box = new HashSet<>();
        /*
        DefendAssert.single(box)
                .notNull()
                .notEmpty()
                .contains(Set.of("nimo"))
                .getError()
                .forEach(pair->System.out.println(String.format("index=%d, has exception=%s", pair.left(), pair.right())));
                */
        PredicateQueue.<Set<String>>require()
                .notEmpty()
                .contains(Set.of("nimo"))
                .asserts(Assertion.single(box))
                .getError()
                .forEach(pair->System.out.println(String.format("index=%d, has exception=%s", pair.left(), pair.right())));
    }
    @Test
    public void testDecimal(){
        // float d = 10.01f;
        // System.out.println(d);
        String val = "";
        /*
        DefendAssert.single("0x100F")
                .notNull()
                .notEmpty()
                .numeric()
                .getError()
                .forEach(pair->System.out.println(String.format("index=%d, has exception=%s", pair.left(), pair.right())));
                */
        PredicateQueue.<String>require()
                .notEmpty()
                .numeric()
                .asserts(Assertion.single(val))
                .getError()
                .forEach(pair->System.out.println(String.format("index=%d, has exception=%s", pair.left(), pair.right())));
    }
    @Test
    public void testContactQueue(){
        String val = null;
        PredicateQueue<String> contactQueue = PredicateQueue.<String>define().unsigned().zero().build();
        PredicateQueue.<String>require()
                .notEmpty()
                .numeric()
                .build()
                .contact(contactQueue)
                .asserts(Assertion.single(val))
                .getError()
                .forEach(pair->System.out.println(String.format("index=%d, has exception=%s", pair.left(), pair.right())));
    }
    @Test
    public void testCQEquals(){
        PredicateQueue.<String>require()
                .equalsTo("work")
                .asserts(Assertion.single("work"))
                .getError()
                .forEach(pair->System.out.println(String.format("index=%d, has exception=%s", pair.left(), pair.right())));

    }
    @Test
    public void testCQMatch(){
        PredicateQueue.<String>require()
                .matchTo(Pattern.compile("[0-9]*"))
                .asserts(Assertion.single("work"))
                .getError()
                .forEach(pair->System.out.println(String.format("index=%d, has exception=%s", pair.left(), pair.right())));
    }

    @Test
    public void testCQDecimal(){
        PredicateQueue.<String>require()
                .decimalScale(2)
                .asserts(Assertion.single("12.3"))
                .getError()
                .forEach(pair->System.out.println(String.format("index=%d, has exception=%s", pair.left(), pair.right())));
    }
    // 地址是否合法
    @Test
    public void testVerify(){
        String url="https://www.baeldung.com/java-check-url-exists";
        String aurl = "http://www.example.com/app/#/home?a=1#b";
        assertTrue(AUrl.isVerify(aurl));
    }
    // 地址是否可访问
    // 链接检查器
    @Test
    public void testActived(){
        String url="https://www.baeldung.com/java-check-url-exists";
        String aurl = "http://www.example.com/app/#/home?a=1#b";
        assertTrue(AUrl.isActive(url));
    }

    // jdk HttpClient
    @Test
    public void testHClient() throws MalformedURLException, URISyntaxException {
        String aurl = "http://www.example.com/app/#/home?a=1";
        HClientExecutor hClientExecutor = AUrl.execute(HClientExecutor.class).arg(aurl);
        HClientResponse<String> response = hClientExecutor.get(aurl, HClientContext.defaultConfig);
        System.out.println(response.message());
        assertEquals(404, response.code());
    }

    // 获取指定地址的json内容
    @Test
    public void testGetJson() throws MalformedURLException, URISyntaxException {
        String url = "http://t.weather.sojson.com/api/weather/city/101030100";
        HClientResponse<String> json = HClientExecutor.getJson(url);
        if(json.statusCode().isSuccess() && json.body().isPresent()){
            System.out.println(json.body().get());
        }
    }
    // 发起HTTP Head请求
    @Test
    public void testHead() throws MalformedURLException, URISyntaxException {
        String url = "http://t.weather.sojson.com/api/weather/city/101030100";
        HClientResponse<Void> response = HClientExecutor.head(url, HClientContext.defaultConfig);
        assertTrue(response.statusCode().isSuccess());
    }

    @Test
    public void testRHead() throws URISyntaxException {
        String url = "http://t.weather.sojson.com/api/weather/city/101030100";
        String aurl = "http://localhost/oams-api/public/index.php/debine";
        HClientResponse<Void> response = HClientRetryExecutor.head(aurl, HClientContext.defaultConfig, HClientRetryExecutor.defaultPolicy);
        // assertTrue(response.statusCode().isSuccess());
        System.out.println(response.statusCode().isSuccess());

        //HClientResponse<String> response = HClientRetryExecutor.getRetry(aurl, HClientContext.defaultConfig);
        //System.out.println(response.body().orElse("NO"));
    }

    public class TBean{
        private int id;
        private String action;

        public TBean(int id, String action) {
            this.id = id;
            this.action = action;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getAction() {
            return action;
        }

        public void setAction(String action) {
            this.action = action;
        }
    }

    /*
    @Test
    public void testOKURL(){
        String a = "https://www.google.com/search?product=1010&page=2";
        HttpUrl tmp = HttpUrl.parse(a);
        AUrlMeta temp = AUrl.parse(a);
        // assumeTrue(temp.getQueryParamSize() == tmp.querySize());
        then(temp.getQueryParamSize()).isEqualTo(tmp.querySize()).isEqualTo(2);

        // assertThat(tmp).usingRecursiveComparison()
        //         .withEqualsForFields(closeEnough, "height")
        //        .isEqualTo(temp);

    }*/
    /*
    @Test
    public void testOKEncode(){
        String a = "https://www.google.com/search?word=java stream map";
        HttpUrl tmp = HttpUrl.parse(a);
        AUrlMeta temp = AUrl.parse(a, new PatternParser());
        assertEquals(tmp.toString(), temp.toString());
    }*/

    /*
    @Test
    public void testClear(){
        String htmlStr = "<p>we can look at the definition of the <a href=\"https://www.yiibai.com/junit-assertions#junit4-assertequals\">JUnit's Assert</a> of our test cases:</p>";
        // 期待
        String expectStr = "<p>we can look at the definition of the JUnit's Assert of our test cases:</p>";

        assertEquals(AUrl.clearHtmlURL(htmlStr).orElse("*"), expectStr);
    }*/
    /*
    @Test
    public void testExtract(){
        String content = "<ul id=\"random-art\"><li><a href=\"https://www.yiibai.com/php/php_functions.html\" target=\"_blank\">PHP函数</a></li><li><a href=\"https://www.yiibai.com/php/php_function_array_splice.html\" target=\"_blank\">PHP array_splice()函数</a></li></ul>";
        List<String> collect = AUrl.extract(content).collect(Collectors.toList());
        // junit
        assumeTrue(
                collect.get(0).equals("https://www.yiibai.com/php/php_functions.html")
                        &&
                        collect.get(1).equals("https://www.yiibai.com/php/php_function_array_splice.html"));
    }*/
    /*
    @Test
    public void testAssertJ(){
        String content = "<ul id=\"random-art\"><li><a href=\"https://www.yiibai.com/php/php_functions.html\" target=\"_blank\">PHP函数</a></li><li><a href=\"https://www.yiibai.com/php/php_function_array_splice.html\" target=\"_blank\">PHP array_splice()函数</a></li></ul>";
        List<String> collect = AUrl.extract(content).collect(Collectors.toList());
        assertThat(collect)
                .hasSize(2)
                .contains("https://www.yiibai.com/php/php_functions.html", Index.atIndex(0))
                .contains("https://www.yiibai.com/php/php_function_array_splice.html", Index.atIndex(1));
    }*/
}
